// 1.call
Function.prototype.call = function (thisArg, ...args) {
    thisArg = thisArg || window
    const fn = Symbol('fn')
    thisArg[fn] = this
    let res = thisArg[fn](...args)
    delete thisArg[fn]
    return res
}

// Test
function fn1 (a, b, c) {
    console.log(this)
    console.log(this.a)
    console.log(a, b, c)
}

fn1.call({ a: 100 }, 10, 20, 30)

let personA = {
    fullName: function (city, country) {
        console.log(this.firstName + ' ' + this.lastName + ',' + city + ',' + country)
    },
}
let personA1 = {
    firstName: 'John',
    lastName: 'Doe',
}
personA.fullName.call(personA1, 'Oslo', 'Norway')

// 2.apply
Function.prototype.apply = function (thisArg, args) {
    thisArg = thisArg || window
    const fn = Symbol('fn')
    thisArg[fn] = this
    let res = thisArg[fn](...args)
    delete thisArg[fn]
    return res
}

// Test
let personB = {
    fullName: function (city, country) {
        console.log(this.firstName + ' ' + this.lastName + ',' + city + ',' + country)
    },
}
let personB1 = {
    firstName: 'John',
    lastName: 'Doe',
}
personB.fullName.apply(personB1, ['Oslo', 'Norway'])

